function HanoiModel(height) {
	this.height = height;
	this.reset();
}

HanoiModel.prototype.reset = function() {
	this.towers = this.getInitialState();
};

HanoiModel.prototype.getInitialState = function() {
	var result = [];

	result[0] = [];
	for ( var i = this.height; i > 0; i--) {
		result[0].push(i);
	}
	result[1] = [];
	result[2] = [];

	return result;
};

HanoiModel.prototype.move = function(from, to) {
	var moved = false;

	if (this.inBounds(from) && this.inBounds(to)) {
		var toLen = this.last(to);
		var fromLen = this.last(from);

		if (fromLen < toLen) {
			moved = true;
			this.swap(from, to);
		}
	}

	return moved;
};

HanoiModel.prototype.inBounds = function(x) {
	return x >= 0 && x < 3;
};

HanoiModel.prototype.last = function(towerIndex) {
	var result = this.height + 1;

	var tower = this.towers[towerIndex];
	if (tower.length > 0) {
		result = tower[tower.length - 1];
	}

	return result;
};

HanoiModel.prototype.swap = function(from, to) {
	var fromTower = this.towers[from];
	var toTower = this.towers[to];

	toTower.push(fromTower.pop());
};

HanoiModel.prototype.getState = function() {
	return this.towers.slice(0);
};

HanoiModel.prototype.solved = function() {
	return (this.towers[0].length === 0) && (this.towers[1].length === 0);
};

/**
 * 
 * @param view
 * @returns
 */
function HanoiController(view, height) {
	this.view = view;
	this.height = height || 3;
}

HanoiController.prototype.startup = function() {
	this.model = new HanoiModel(this.height);
	this.view.init(this);
	this.updateView();
};

HanoiController.prototype.updateView = function() {
	this.view.update(this.model.getState());
};

HanoiController.prototype.onMove = function(from, to) {
	var moved = this.model.move(from, to);

	if (moved) {
		this.updateView();
	}

	if (this.checkSolved()) {
		var id = "hanoi" + ((this.height === 3) ? "" : this.height);
		new AEnigmatesStorage(id).solved();
		this.view.onSolved();
	}

	return moved;
};

HanoiController.prototype.checkSolved = function() {
	return this.model.solved();
};